<template>
  <div class="player por ovh" :class="{'full-screen-box': isFullScreen}"
       @mousemove="showControls"
       @mouseleave="showCtr = false">
    <video-player class="video-player vjs-custom-skin h100 vam"
                  ref="videoPlayer"
                  :playsinline="true"
                  :options="playerOptions"
                  @ready="onPlayerReady"
                  @loadeddata="onPlayerLoadedData"
                  @play="onPlayerPlay"
                  @playing="onPlayerPlaying"
                  @timeupdate="onPlayerTimeUpdate"
                  @pause="onPlayerPause"
                  @ended="onPlayerEnded">
    </video-player>
  </div>
</template>

<script>
  import 'video.js/dist/video-js.css';
  import {videoPlayer, videojs} from 'vue-video-player';
  import 'videojs-contrib-hls';

  export default {
    props: {
      videoSrc: {
        type: String,
        default: ''
      },
      poster: {
        type: String,
        default: ''
      },
      aspect: {
        type: String,
        default: '16:9'
      },
    },
    filters: {
    },
    data() {
      return {
        unHover: false,
        playing: false,

        controls: {
          left: [
            {type: 'play-btn'},
            {type: 'time', value: '$c / $d'}, // $c：当前时间; $s：剩余时间; $d：总时间,
            {type: 'voice'},
          ],
          right: [
            {type: 'list-btn', options: ['1.0x', '1.25x', '1.5x', '2.0x'], value: '1.0x', prop: 'rate'},
            {type: 'list-btn', options: ['标清', '高清', '超清', '默认'], value: '默认', prop: 'definition'},
            {type: 'full-btn'},
          ]
        },

        playerOptions: {
          playbackRates: [1.0, 1.25, 1.5, 2.0], //播放速度
          autoplay: true, //如果true,浏览器准备好时开始回放。
          muted: false, // 默认情况下将会消除任何音频。
          loop: false, // 导致视频一结束就重新开始。

          controls: true, // 是否显示播放控件

          preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频（如果浏览器支持）
          language: 'zh-CN',
          aspectRatio: '', // 将播放器置于流畅模式，并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字（例如"16:9"或"4:3"）
          fluid: true, // 当true时，Video.js player将拥有流体大小。换句话说，它将按比例缩放以适应其容器。
          sources: [],
          poster: '', //你的封面地址
          width: document.documentElement.clientWidth,
          flash: {hls: {withCredentials: false}},
          html5: {hls: {withCredentials: false}},
          notSupportedMessage: '此视频暂时无法播放', //允许覆盖Video.js无法播放媒体源时显示的默认信息。
          controlBar: {
            timeDivider: true,
            durationDisplay: true,
            remainingTimeDisplay: false,
            fullscreenToggle: true  //全屏按钮
          }
        },
        typeObj: {
          //你的m3u8地址（必填）application/x-mpegURL
          m3u8: 'application/x-mpegURL',
          //你的mp4地址（必填）video/mp4
          mp4: 'video/mp4',
        },
        defaultVideoType: 'video/mp4',

        player: null,
        isFullScreen: false,
        showCtr: false,
        ctrTimer: null,
        currentTime: 0,
        duration: 0,
        surplus: 0,
        volume: 0,
      }
    },
    components: {
      videoPlayer
    },
    watch: {
      videoSrc(val) {
        this.setPlayUrl();
      }
    },
    methods: {
      onPlayerReady(player) {
        this.$emit('ready', player);
      },
      onPlayerLoadedData(player) {
        this.player = player;
        this.duration = player.duration();
        this.currentTime = 0;
        this.volume = player.volume();
        this.playing = false;
        this.$emit('load', player);
      },
      setVolume(e) {
        let w = this.$refs.volumeBox[0].offsetWidth;
        let curr = e.offsetX;
        this.volume = curr / w;
        this.player.volume(curr / w);
      },
      setCurrentTime(e) {
        let w = this.$refs.myBottomControls.offsetWidth;
        let curr = e.offsetX;
        let y = e.offsetY;
        let isActive = e.target.className.split(/\s+/ig).includes('current-time-line');
        (isActive || y <= 0) && this.player.currentTime(curr / w * this.duration);
      },
      showControls() {
        clearTimeout(this.ctrTimer);
        this.showCtr = true;
        this.ctrTimer = setTimeout(() => {
          this.showCtr = false;
        }, 2500);
      },
      play() {
        if (this.playing) {
          this.player.pause();
        } else {
          this.player.play();
        }
      },
      onPlayerPlay(player) {
        this.playing = true;
        this.$emit('play', player);
      },
      onPlayerPlaying(player) {
        this.$emit('playing', player);
      },
      onPlayerTimeUpdate(player) {
        this.currentTime = player.currentTime();
        this.surplus = this.duration - this.currentTime;
        this.$emit('timeupdate', player);
      },
      onPlayerEnded(player) {
        this.$emit('ended', player);
      },
      onPlayerPause(player) {
        this.playing = false;
        this.$emit('pause', player);
      },
      fullScreen() {
        let el = document.documentElement;
        let full = [
          'requestFullscreen',
          'msRequestFullscreen',
          'mozRequestFullScreen',
          'webkitRequestFullscreen',
        ];
        let doc = document;
        let exit = [
          'exitFullscreen',
          'msExitFullscreen',
          'mozCancelFullScreen',
          'webkitExitFullscreen',
        ];
        if (this.isFullScreen) {
          // 退出全屏
          for (let e of exit) {
            if (doc[e]) {
              doc[e]();
              break;
            }
          }
        } else {
          // 全屏
          for (let e of full) {
            if (el[e]) {
              el[e]();
              break;
            }
          }
        }
      },
      setRate(text) {
        text = parseFloat(text);
        this.player.playbackRate(text);
      },
      optionsCallback(item, text, e) {
        item && (item.value = text);
        if (item.prop === 'rate') {
          this.setRate(text);
        }
        this.$emit('optionsCallback', item);
        this.unHover = true;
        setTimeout(() => {
          this.unHover = false;
        }, 300);
      },
      setPlayUrl() {
        let videoType = this.videoSrc.split('.').pop();
        this.playerOptions.sources = [
          {
            withCredentials: false,
            type: this.typeObj[videoType] || this.defaultVideoType,
            src: this.videoSrc
          }
        ];
        this.playerOptions.poster = this.poster;
      },
      winFullCallback(e) {
        this.isFullScreen = !!(document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement || document.fullscreenElement);
      },
    },
    computed: {
      // player(player) {
      //   return this.$refs.videoPlayer.player;
      // }
    },
    created() {
      // return;
      this.playerOptions.aspectRatio = this.aspect;
      if (this.videoSrc) {
        this.setPlayUrl();
      }
      window.removeEventListener('resize', this.winFullCallback);
      window.addEventListener('resize', this.winFullCallback);
    },
  }
</script>

<style scoped lang="less">
  .full-screen-box {
    position: fixed;
    z-index: 10000;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
  }

  .my-play-controls {
    .my-bottom-controls {
      transform: translateY(100% - 5px);
      &.show-controls {
        transform: translateY(0);
      }
      transition: transform .3s;
      color: #fff;
      font-size: 12px;
      line-height: 37px;
      height: 37px;
      background-color: rgba(0, 0, 0, .4);
      opacity: .8;
      border-top: 5px solid #1c455d;
    }
    .current-time-line {
      top: -5px;
      height: 5px;
      background-color: #188eee;
      .circle {
        width: 6px;
        height: 6px;
        border: 3px #fff solid;
        border-radius: 50%;
        background-color: #188eee;
        transform: translate(50%, -33%);
      }
    }
    .play-btn {
      margin: 0 19px 0 12px;
      color: #188eee;
      font-size: 28px;
      line-height: 37px;
      &.playing {
        &:after {
          content: '';
          margin: 14px 8px 0;
          display: inline-block;
          vertical-align: top;
          width: 4px;
          height: 10px;
          border-right: 4px solid #fff;
          border-left: 4px solid #fff;
        }
      }
    }
    .voice {
      margin-left: 32px;
      font-size: 20px;
      line-height: 34px;
      .voice-img {
        width: 15px;
        height: 15px;
      }
      .voice-line {
        width: 67px;
        height: 5px;
        border-radius: 10px;
        background-color: #9498a5;
        .line-inner {
          border-radius: 10px;
          background-color: #fff;
        }
      }
    }

    .full-screen {
      margin: 0 12px 0 20px;
      font-size: 20px;
      line-height: 37px;
    }
    .definition {
      margin-left: 8px;
      width: 50px;
    }
    .select {
      width: 50px;
      &:hover {
        color: #00b776;
        .select-box {
          transform: translateY(-100%);
          background-color: #071d19;
          color: #e8e8f0;
          opacity: .9;
          .active {
            color: #00b776;
          }
        }
      }
      .select-box {
        opacity: 0;
        .select-item {
          &:hover {
            background-color: #22413d;
          }
        }
      }
    }
  }
</style>
